Skip to content

ux: usability pass — 10 web-client fixes (Nielsen heuristics + Don't Make Me Think)#92

Merged
dmccoystephenson merged 10 commits into
mainfrom
feature/web-ux-pass-2
Jun 13, 2026
Merged

ux: usability pass — 10 web-client fixes (Nielsen heuristics + Don't Make Me Think)#92
dmccoystephenson merged 10 commits into
mainfrom
feature/web-ux-pass-2

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

A multi-round Nielsen/Krug usability pass on the web front-end client (src/ui/webUserInterface.py). Every commit is one self-contained, heuristic-cited fix, scoped small for review. (Round 1 — keyboard control, destructive-color, disconnect handling — shipped earlier in #91.)

Round 2 — Onboarding & control discoverability

  1. Tagline under the heading explains the game and the $10,000 goal before the first click. (Nielsen Made price for bait persistent. #10; Krug: answer the obvious question)
  2. Controls hint makes the keyboard shortcuts visible. (Nielsen Create 'Prompt' class to store the current prompt. #6; Krug: visible options)

Round 3 — System-status visibility

  1. Low-energy cue — energy turns bold red below the fishing threshold (10), warning before a wasted trip to the docks. (Nielsen Apache License #1, Make data persistent w/ JSON. #5)
  2. Tab title reflects Day + money so progress is visible from a background tab. (Nielsen Apache License #1)

Round 4 — Aesthetic & layout

  1. Status header is now a flex-wrap row of chips that degrades cleanly on narrow screens instead of one overflowing pipe-separated line. (Nielsen Starter Money #8)
  2. Loading/ended states render through a consistent styled notice instead of bare text nodes. (Nielsen Fix game crashing when attempting to deposit/withdraw $0 after entering a non-number. #4, Starter Money #8)

Round 5 — Numeric input affordance & error prevention

  1. Numeric prompts flagged server-side (promptForNumber tags the screen). (Nielsen Make data persistent w/ JSON. #5, Create 'Prompt' class to store the current prompt. #6)
  2. Client guards numeric input — decimal keypad, placeholder, and Submit/Enter disabled until the value parses as a number, so an invalid amount can't be sent. (Nielsen Make data persistent w/ JSON. #5, Create 'Prompt' class to store the current prompt. #6)

Round 6 — Action affordances & feedback consistency

  1. Single-action buttons (Continue / React! / Submit) get a distinct accent style so the one thing to do doesn't look like one option among many. (Nielsen Fix game crashing when attempting to deposit/withdraw $0 after entering a non-number. #4; Krug: self-evident)
  2. Disconnect banner restyled as an amber warning, distinct from blue info notices. (Nielsen Data Persistence w/ JSON #9, Apache License #1)

Test plan

  • python3 -m pytest — 198 passed; client JS passes node --check
  • New player sees the tagline + controls hint; pressing a number key chooses an option
  • Energy goes red when < 10; tab title shows Day/money
  • On a phone-width window the status header wraps cleanly
  • A bank/tavern amount field shows a number pad, rejects empty/non-numeric, and only enables Submit when valid
  • Continue/React!/Submit look distinct from option lists; killing the game shows an amber "Lost connection" banner

🤖 Generated with Claude Code

dmccoystephenson and others added 10 commits June 13, 2026 12:49
A new player opening the page saw only the word "FishE" above a save-file menu,
with no indication of what the game is or what they're working toward. They had
to start playing to infer the point (Nielsen #10 help and documentation; Krug:
answer the obvious question before it's asked).

The heading now carries a one-line tagline — "fish a seaside village and build a
fortune of $10,000" — so the premise and the win condition are clear before the
first click.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous round added number-key and Enter/Space shortcuts, but nothing on
the page hinted they existed, so a player would only find them by accident. A
feature the user can't see effectively doesn't exist (Nielsen #6 recognition
rather than recall; Krug: visible options).

A small persistent hint under the play area now states that options can be
clicked or chosen by number key and that Enter/Space continues, making the
shortcuts a recognizable affordance rather than a hidden one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Energy rendered as a plain number alongside the other stats, so a player had no
warning they were too tired to fish until they walked to the docks, chose Fish,
and got "You're too tired to fish! Go home and sleep." The status the game
already tracks wasn't surfaced where it mattered (Nielsen #1 visibility of
system status; Nielsen #5 error prevention).

The header is now built from parts so the energy value can stand out: when it
drops below the fishing threshold (10) it renders bold red, signalling "rest
before you head out" before the player makes a wasted trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The tab title was a constant "FishE", so a player with the game in a background
tab had no way to glance at their progress without switching to it — the system
status stopped at the edge of the page (Nielsen #1 visibility of system status).

The title now updates each turn to "FishE — Day N, $X", so day and cash are
visible in the tab strip even when the game isn't the focused tab.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The header was a single text line ("Day 3 | 8:00 AM | $120.00 | Fish: 4 |
Energy: 100 | Docks | Goal: ...") joined by pipe separators. On a narrow or
phone-width viewport that line wrapped mid-token, and the run of " | " noise
worked against readability (Nielsen #8 aesthetic and minimalist design).

The header is now a flex-wrap row of individual stat chips spaced by whitespace,
so it stays on one line when there's room and wraps cleanly to multiple rows
when there isn't — no stray separators and no awkward mid-token breaks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Waiting for the game…" and "The game has ended." messages were appended as
bare text nodes directly to the body, so they sat flush against the top edge
with none of the spacing or color the rest of the screens use — they read as
unfinished compared to every other state (Nielsen #4 consistency and standards;
Nielsen #8 aesthetic and minimalist design).

Both now render through a shared notice helper with a consistent style, matching
the look of the rest of the UI (and giving the disconnect banner the same
helper).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Amount prompts (bank deposit/withdraw, tavern bet) reached the browser as a
generic text prompt, so the client had no way to know a number was expected —
it couldn't offer a numeric keypad or stop the player from submitting "abc"
(which the game would silently reject with a "Try again" on the next screen).
That's a missed chance at error prevention and at matching input to the real
expected type (Nielsen #5 error prevention; Nielsen #6 recognition).

WebUserInterface now overrides promptForNumber to tag the prompt screen as
numeric (the base default can't, since it only knows it's parsing text). The
client picks this up in the next commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When a prompt is numeric the input was a plain text box that accepted anything
and a Submit button that always fired, so a player could submit an empty or
non-numeric value and only discover the mistake when the game bounced them back
with "Try again" on the following screen (Nielsen #5 error prevention; Nielsen
#6 recognition rather than recall).

For numeric prompts the field now requests a decimal keypad, shows an "Enter a
number" placeholder, and the Submit button (and Enter) stay disabled until the
value parses as a number — so an invalid amount can't be sent in the first
place. Non-numeric prompts are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Continue, React!, and Submit rendered as full-width, left-aligned buttons
identical to the entries in an option list, so the one obvious thing to do
looked like just another choice in a menu — the player had to read to tell a
sole action apart from a list (Nielsen #4 consistency and standards; Krug:
the actionable thing should look obviously actionable).

These single-action buttons now use an accent "action" style — auto width,
centered, brighter color — so they clearly read as "the button to press" rather
than one option among several.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The disconnect banner reused the same blue "notice" style as benign status
messages like "Waiting for the game…", so a genuine problem (the game stopped
responding) read as ordinary information and was easy to overlook (Nielsen #9
help users recognize and recover from errors; Nielsen #1 visibility of system
status — error states should look different from normal ones).

It now renders with a distinct amber warning style and accent border, so a lost
connection stands out from informational notices.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dmccoystephenson dmccoystephenson changed the title ux: usability pass — 11 web-client fixes (Nielsen heuristics + Don't Make Me Think) ux: usability pass — 10 web-client fixes (Nielsen heuristics + Don't Make Me Think) Jun 13, 2026

@dmccoystephenson dmccoystephenson left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review (Nielsen/Krug pass, 5 rounds):

  • Each commit is one heuristic-cited fix with a concrete player-observable problem; no nitpicks/padding.
  • Scope: web client only (HTML/JS in webUserInterface.py) + one server-side numeric-prompt flag with a test. No protected/persistence paths; console & pygame untouched.
  • Verified: client JS passes node --check after each round; full suite 198 passed; CI green.
  • Discoverability (tagline, controls), status visibility (low-energy, tab title), layout (wrapping header, consistent notices), input safety (numeric guard), affordance consistency (action buttons, warning banner).

@dmccoystephenson dmccoystephenson merged commit f11ef7f into main Jun 13, 2026
1 check passed
@dmccoystephenson dmccoystephenson deleted the feature/web-ux-pass-2 branch June 13, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant